const http = require('http');
const WebSocket = require('ws');

const CONFIG = {
    host: 'localhost',
    port: 3000,
    mobile: '17091271111',
    passwordHash: 'e10adc3949ba59abbe56e057f20f883e',
    targetVip: 2,
    injectAmount: 20000,
};

async function httpReq(path, method, data) {
    return new Promise((resolve, reject) => {
        const options = {
            hostname: CONFIG.host,
            port: CONFIG.port,
            path,
            method,
            headers: { 'Content-Type': 'application/json' },
        };
        const req = http.request(options, (res) => {
            let body = '';
            res.on('data', (c) => (body += c));
            res.on('end', () => {
                try { resolve(JSON.parse(body)); } catch { resolve({}); }
            });
        });
        req.on('error', reject);
        if (data) req.write(JSON.stringify(data));
        req.end();
    });
}

async function run() {
    // 1) login
    const login = await httpReq('/user-service/user/login', 'POST', {
        mobile: CONFIG.mobile,
        pwd: CONFIG.passwordHash,
    });
    if (login.code !== 0 || !login.data?.accessToken) throw new Error('login failed');
    const token = login.data.accessToken;

    // 2) connect ws
    const url = `ws://${CONFIG.host}:${CONFIG.port}/user-service/websocket?t=${token}`;
    const ws = await new Promise((resolve, reject) => {
        const w = new WebSocket(url);
        w.on('open', () => resolve(w));
        w.on('error', reject);
    });

    const send = (obj) => ws.send(JSON.stringify(obj));
    const wait = (pred, timeout = 10000) => new Promise((resolve, reject) => {
        let done = false;
        const handler = (data) => {
            try {
                const msg = JSON.parse(data.toString());
                if (pred(msg)) {
                    ws.removeListener('message', handler);
                    done = true;
                    resolve(msg);
                }
            } catch { }
        };
        ws.on('message', handler);
        setTimeout(() => { if (!done) { ws.removeListener('message', handler); reject(new Error('timeout')); } }, timeout);
    });

    // 3) roles & select
    send({ c: 3, d: null });
    await wait((m) => m.act_id === 3);
    send({ c: 4, d: { characterId: 2001 } });
    await wait((m) => m.act_id === 4 && m.code === 0);

    // 4) reset vip
    send({ c: 61021, d: {} });
    await wait((m) => m.act_id === 61021 && m.code === 0);

    // 5) inject 20000
    send({ c: 61020, d: { next: CONFIG.injectAmount } });
    const inj = await wait((m) => m.act_id === 61020);

    // 6) query 6102
    send({ c: 6102, d: { lvl: -2 } });
    const info = await wait((m) => m.act_id === 6102 && m.code === 0);
    const vipLvl = info?.data?.vipLvl ?? -1;

    const success = vipLvl >= CONFIG.targetVip;
    const summary = { success, vipLvl, injected: CONFIG.injectAmount, injData: inj?.data || null };
    console.log(JSON.stringify(summary));
    ws.close();
    process.exit(success ? 0 : 1);
}

run().catch((e) => { console.error('ERR', e.message); process.exit(1); });


